package com.example.wnn.utils;

import com.alibaba.druid.util.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class VersionCompareUtil {

    private static final Pattern num = Pattern.compile("[^0-9]");
    private static final Pattern cha = Pattern.compile("\\D+");

    /**
     * 版本号对比， 默认字符大于数字: 如("10.0.1b", "10.0.1a")
     *
     * @param ver1 版本号1
     * @param ver2 版本号2
     * @return 版本号1 是否大于等于 版本号2
     */
    public static boolean versionCompare(String ver1, String ver2) {

        ver1 = StringUtils.isEmpty(ver1) ? "99.99" : ver1;
        ver2 = StringUtils.isEmpty(ver2) ? "99.99" : ver2;

        String[] verA = ver1.split("\\.", -1);
        String[] verB = ver2.split("\\.", -1);

        int com;
        int len = Math.max(verA.length, verB.length);
        // 补齐字符串数组
        if (verA.length < len)
            verA = stringExt(verA, len);
        else if (verB.length < len)
            verB = stringExt(verB, len);

        for (int i = 0; i < len; i++) {
            try {
                com = Integer.parseInt(verA[i]) - Integer.parseInt(verB[i]);
            } catch (Exception e) {
                log.error(String.format("versionCompare err: ver1=>%s, ver1=>%s", ver1, ver2), e);
                com = numAndCharCompare(verA[i], verB[i]);
            }

            if (com > 0) return true;
            else if (com < 0) return false;
        }


        return true;
    }

    /**
     * 数字与字符组成字符串大小比较，如：(10a 9a)，(9a 9)，(9b 9a)
     *
     * @param left
     * @param right
     * @return 1、0、-1
     */
    public static int numAndCharCompare(String left, String right) {

        left = left.length() == 0 ? "0" : left;
        right = right.length() == 0 ? "0" : right;

        // 判断字符串首字符是否为数字
        boolean bL = left.charAt(0) >= 48 && left.charAt(0) <= 57;
        boolean bR = right.charAt(0) >= 48 && right.charAt(0) <= 57;
        if (bL && !bR)
            return -1;
        else if (!bL && bR)
            return 1;

        // 获取数字
        String[] numLeft = num.matcher(left).replaceAll(",").split(",");
        String[] numRight = num.matcher(right).replaceAll(",").split(",");

        // 获取字符串
        List<String> charLeft = new ArrayList<>();
        List<String> charRight = new ArrayList<>();
        Matcher matcherL = cha.matcher(left);
        Matcher matcherR = cha.matcher(right);
        while (matcherL.find()) {
            charLeft.add(matcherL.group(0));
        }
        while (matcherR.find()) {
            charRight.add(matcherR.group(0));
        }

        int numL = numLeft.length;
        int numR = numRight.length;
        int numLen = Math.max(numL, numR);
        // 补齐字符串数组
        if (numL < numLen)
            numLeft = stringExt(numLeft, numLen);
        else if (numR < numLen)
            numRight = stringExt(numRight, numLen);


        // 补齐List
        int charL = charLeft.size();
        int charR = charRight.size();
        int charMax = Math.max(charL, charR);
        if (charL < charMax)
            listExt(charLeft, charL, charMax);
        else if (charR < charMax)
            listExt(charRight, charR, charMax);

        int com = 0;
        if (bL) // 同为数字开头
        {
            for (int i = 0; i < numLen; i++) {
                com = Integer.parseInt(numLeft[i]) - Integer.parseInt(numRight[i]);
                if (com == 0 && i < charMax)
                    com = charLeft.get(i).compareTo(charRight.get(i));

                if (com > 0) return 1;
                else if (com < 0) return -1;
            }
        } else {
            for (int i = 0; i < charMax; i++) {
                com = charLeft.get(i).compareTo(charRight.get(i));
                if (com == 0 && i < numLen)
                    com = Integer.parseInt(numLeft[i + 1]) - Integer.parseInt(numRight[i + 1]);

                if (com > 0) return 1;
                else if (com < 0) return -1;
            }
        }

        return 0;
    }

    /**
     * 补齐字符串数组长度
     *
     * @param data 字符串数组
     * @param len  补齐长度
     * @return 补齐后的数组
     */
    public static String[] stringExt(String[] data, int len) {
        String[] res = new String[len];

        int index = 0;
        for (String datum : data) {
            res[index++] = datum;
        }

        while (index < len) {
            res[index++] = "0";
        }

        return res;
    }

    /**
     * 补齐List长度
     *
     * @param data list
     * @param size 自身长度
     * @param len  补齐长度
     */
    public static void listExt(List<String> data, int size, int len) {
        while (size < len) {
            data.add("0");
            size++;
        }
    }


    public static void main(String[] args) {
        System.out.println(versionCompare("10.0.0", "10.0.0"));
        System.out.println(versionCompare("5.0.0.5", "10.0.0"));
        System.out.println(versionCompare("5.0.0.5", "3.0.1"));
        System.out.println(versionCompare("10.0.0", "9.0.0"));
        System.out.println(versionCompare("10.1.0", "10.0.0"));
        System.out.println(versionCompare("10.0.1b", "10.0.1a"));
        System.out.println(versionCompare("10.0._0", "10.0._0_"));
        System.out.println(versionCompare("9..", "9.0.0"));
    }


}
